import { Node, Vec3 } from "cc";
import { app } from "db://app-game/core/app";
import { ecs } from "db://app-game/libs/ecs/ECS";
import { ECSEntity } from "db://app-game/libs/ecs/ECSEntity";
import RVOMath from "db://app-game/libs/math/rov2/RVOMath";
import Vector2D from "db://app-game/libs/math/rov2/Vector2D";
import { GameStorage } from "../../../common/config/GameStorage";
import { DBLevelType } from "../../../common/db/db-level/DBLevel.type";
import { Joysitick } from "../../../ecs/joysitick/Joysitick";
import { MapE } from "../../../ecs/map/Map";
import { Role } from "../../../ecs/role/Role";
import { Level } from "../Level";
import { LevelBaseModelComp } from "../model/LevelBaseModelComp";
import { MonsterFactoryComp } from "../model/MonsterFactoryComp";
import { LevelViewComp } from "../view/LevelViewComp";
import { SkillIcon } from "../../../ecs/skill-icon/SkillIcon";

/** 关卡进入系统 */
@ecs.register("Level")
export class LevelSystem
  extends ecs.ComblockSystem
  implements ecs.IEntityEnterSystem, ecs.ISystemUpdate
{
  filter(): ecs.IMatcher {
    return ecs.allOf(LevelBaseModelComp, LevelViewComp);
  }
  async entityEnter(entity: ECSEntity): Promise<void> {
    const level = entity as Level;
    // 1.数据层渲染
    this.dataLayerRender(level);
    // 2.UI层渲染
    this.uiLayerRender(level);

    // 3.添加组件
    this.addComponent(level);
  }

  /** 数据层渲染 */
  dataLayerRender(level: Level) {}

  /** UI层渲染 */
  uiLayerRender(level: Level) {
    const { data } = level.get(LevelBaseModelComp);
    const { creatureNode, uiNode } = level.get(LevelViewComp);
    const userData = app.storage.getJson(GameStorage.Account);
    // 1.渲染地图
    this.mapRender(level, data);
    // 2.渲染UI层
    this.uiRender(level, data, uiNode, userData);
    // 3.渲染角色
    this.roleRender(level, data, creatureNode, userData);

    let obstacle1: Vector2D[] = [];
    obstacle1.push(new Vector2D(-10.0, 40.0));
    obstacle1.push(new Vector2D(-80.0, 40.0));
    obstacle1.push(new Vector2D(-80.0, 10.0));
    obstacle1.push(new Vector2D(-10.0, 10.0));
    level.simulator.addObstacle(obstacle1);

    let obstacle2: Vector2D[] = [];
    obstacle2.push(new Vector2D(50.0, 60.0));
    obstacle2.push(new Vector2D(30.0, 30.0));
    obstacle2.push(new Vector2D(50.0, -10.0));
    obstacle2.push(new Vector2D(80.0, 20.0));
    obstacle2.push(new Vector2D(70.0, 60.0));
    level.simulator.addObstacle(obstacle2);
    level.simulator.processObstacles();
  }

  /** 添加组件 */
  addComponent(level: Level) {
    // 1.添加怪兽工厂组件
    level.add(MonsterFactoryComp);
    level.MonsterFactory.init({ node: level.map.monsterFactoryNode });
  }

  /** 地图渲染 */
  mapRender(level: Level, data: DBLevelType) {
    level.map = ecs.getEntity<MapE>(MapE);
    level.map.loadInitMap(data.mapId);
    level.addChild(level.map);
  }

  /** 角色渲染 */
  roleRender(level: Level, data: DBLevelType, parent: Node, userData: any) {
    // 1.创建角色
    level.controlRole = ecs.getEntity<Role>(Role);
    const params = {
      id: 1,
      userId: userData.id,
      parent,
      pos: Vec3.ZERO,
    };
    level.controlRole.load(params);
    level.addChild(level.controlRole);

    // 2.摄像机跟随
    const roleNode = level.controlRole.RoleModel.node;
    level.camera.setfollowTarget(roleNode);
    level.map.setfollowTarget(roleNode);
  }

  /** 渲染UI层 */
  uiRender(level: Level, data: DBLevelType, parent: Node, userData: any) {
    // 1.摇杆渲染
    this.joysitickRender(level, parent);

    // 2.渲染技能按钮
    this.skillButtonRender(level, parent);
  }

  /** 摇杆渲染 */
  joysitickRender(level: Level, parent: Node) {
    // 1 加载移动摇杆
    level.UILayerEntityGroup.moveJoysitick =
      ecs.getEntity<Joysitick>(Joysitick);
    const moveParams = {
      id: 0,
      parent,
    };
    level.UILayerEntityGroup.moveJoysitick.load(moveParams);
    level.addChild(level.UILayerEntityGroup.moveJoysitick);

    // 2 加载射击摇杆
    level.UILayerEntityGroup.shootJoysitick =
      ecs.getEntity<Joysitick>(Joysitick);
    const shootParams = {
      id: 1,
      parent,
    };
    level.UILayerEntityGroup.shootJoysitick.load(shootParams);
    level.addChild(level.UILayerEntityGroup.shootJoysitick);

    // 3 加载攻击摇杆
    level.UILayerEntityGroup.closeCombatJoysitick =
      ecs.getEntity<Joysitick>(Joysitick);
    const closeCombatParams = {
      id: 2,
      parent,
    };
    level.UILayerEntityGroup.closeCombatJoysitick.load(closeCombatParams);
    level.addChild(level.UILayerEntityGroup.closeCombatJoysitick);
  }

  /** 技能按键渲染 */
  skillButtonRender(level: Level, parent: Node) {
    // 1.加载技能图标1
    const skill_1 = ecs.getEntity<SkillIcon>(SkillIcon);
    skill_1.load(0, parent);
    const skill_2 = ecs.getEntity<SkillIcon>(SkillIcon);
    skill_2.load(1, parent);
  }

  /** 更新 */
  update(level: Level, dt: number): void {
    // 1.模拟器步骤
    this.simulatorStep(level);
  }

  /** 模拟器步骤 */
  simulatorStep(level: Level) {
    let simulator = level.simulator;
    // 遍历所有智能体
    for (let i = 0; i < simulator.getNumAgents(); ++i) {
      // 计算智能体当前位置与目标位置之间的距离的平方
      if (
        RVOMath.absSq(
          simulator.getGoal(i).minus(simulator.getAgentPosition(i))
        ) < RVOMath.RVO_EPSILON
      ) {
        // 如果距离小于预设的阈值，说明智能体已接近目标
        // 将智能体的期望速度设置为零
        simulator.setAgentPrefVelocity(i, 0.0, 0.0);
        // console.log('finish ' + i);
      } else {
        // 如果智能体距离目标较远
        // 计算一个指向目标的单位向量，并将其缩放为一定的速度
        // let v = RVOMath.normalize(simulator.getGoal(i).minus(simulator.getAgentPosition(i))).scale(simulator.agents[i].maxSpeed);
        let v = RVOMath.normalize(
          simulator.getGoal(i).minus(simulator.getAgentPosition(i))
        ).scale(2);
        // 设置智能体的期望速度
        simulator.setAgentPrefVelocity(i, v.x, v.y);
      }
    }

    // 运行模拟，更新智能体的位置和状态
    simulator.run();

    // console.log(simulator)
    // 检查是否所有智能体都到达了目标位置
    if (simulator.reachedGoal()) {
      // 停止定时器（此处注释掉了）
      // Laya.timer.clear(this, this.step);
      console.log("finish");
    }
  }
}
